xen: XSPolicy.can_run hypervisor support
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 1 Apr 2008 09:06:58 +0000 (10:06 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 1 Apr 2008 09:06:58 +0000 (10:06 +0100)
Add functionality for checking whether a domain is in a conflict set
with existing domains.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
xen/include/public/xsm/acm.h
xen/include/xsm/acm/acm_hooks.h
xen/xsm/acm/acm_chinesewall_hooks.c
xen/xsm/acm/acm_policy.c
xen/xsm/acm/acm_simple_type_enforcement_hooks.c

index 09e7879238e8811f1aa2567d3e6897286dad2a97..a66d399c6cd7d474893851ea7b8cf0df250d6768 100644 (file)
@@ -102,6 +102,7 @@ typedef uint32_t ssidref_t;
 #define ACMHOOK_none          0
 #define ACMHOOK_sharing       1
 #define ACMHOOK_authorization 2
+#define ACMHOOK_conflictset   3
 
 /* -------security policy relevant type definitions-------- */
 
index 35ea144378bde99ba7f80f4103ef14ef37893e74..19e37f9e2eee3bf85690581aa7204ad7105fe035 100644 (file)
@@ -116,6 +116,7 @@ struct acm_operations {
                                         ssidref_t ssidref2);
     int (*authorization)               (ssidref_t ssidref1,
                                         ssidref_t ssidref2);
+    int (*conflictset)                 (ssidref_t ssidref1);
     /* determine whether the default policy is installed */
     int (*is_default_policy)           (void);
 };
@@ -151,6 +152,8 @@ static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
 { return 0; }
 static inline int acm_authorization(ssidref_t ssidref1, ssidref_t ssidref2)
 { return 0; }
+static inline int acm_conflictset(ssidref_t ssidref1)
+{ return 0; }
 static inline int acm_domain_create(struct domain *d, ssidref_t ssidref)
 { return 0; }
 static inline void acm_domain_destroy(struct domain *d)
@@ -329,6 +332,17 @@ static inline int acm_authorization(ssidref_t ssidref1, ssidref_t ssidref2)
 }
 
 
+static inline int acm_conflictset(ssidref_t ssidref1)
+{
+    if ((acm_primary_ops->conflictset != NULL) &&
+        acm_primary_ops->conflictset(ssidref1))
+        return ACM_ACCESS_DENIED;
+    else if ((acm_secondary_ops->conflictset != NULL) &&
+             acm_secondary_ops->conflictset(ssidref1))
+        return ACM_ACCESS_DENIED;
+    return ACM_ACCESS_PERMITTED;
+}
+
 /* Return true iff buffer has an acm policy magic number.  */
 extern int acm_is_policy(char *buf, unsigned long len);
 
index a6e2eb3949dfcc31e6eaf0f991d9b2ad351d15bc..65e60e7cb480d76e582575187a4e29257e6850d7 100644 (file)
@@ -641,6 +641,41 @@ static int chwall_is_default_policy(void)
              (chwall_bin_pol.max_ssidrefs == 2 ) );
 }
 
+
+static int chwall_is_in_conflictset(ssidref_t ssidref1)
+{
+    /* is ssidref1 in conflict with any running domains ? */
+    int rc = 0;
+    int i, j;
+    ssidref_t ssid_chwall;
+
+    read_lock(&acm_bin_pol_rwlock);
+
+    ssid_chwall = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref1);
+
+    if ( ssid_chwall >= 0 && ssid_chwall < chwall_bin_pol.max_ssidrefs ) {
+        for ( i = 0; i < chwall_bin_pol.max_conflictsets && rc == 0; i++ ) {
+            for ( j = 0; j < chwall_bin_pol.max_types; j++ ) {
+                if ( chwall_bin_pol.conflict_aggregate_set
+                                 [i * chwall_bin_pol.max_types + j] &&
+                     chwall_bin_pol.ssidrefs
+                                 [ssid_chwall * chwall_bin_pol.max_types + j])
+                {
+                    rc = 1;
+                    break;
+                }
+            }
+        }
+    } else {
+        rc = 1;
+    }
+
+    read_unlock(&acm_bin_pol_rwlock);
+
+    return rc;
+}
+
+
 struct acm_operations acm_chinesewall_ops = {
     /* policy management services */
     .init_domain_ssid = chwall_init_domain_ssid,
@@ -666,6 +701,7 @@ struct acm_operations acm_chinesewall_ops = {
     /* generic domain-requested decision hooks */
     .sharing = NULL,
     .authorization = NULL,
+    .conflictset = chwall_is_in_conflictset,
 
     .is_default_policy = chwall_is_default_policy,
 };
index a7eff56903c7e2cd22bddd473f96fb4e12b42afb..3f66e8ae73e089bfdb2df914052dd6a32dfd1edd 100644 (file)
@@ -446,6 +446,9 @@ acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook)
         ret = acm_authorization(ssidref1, ssidref2);
         break;
 
+    case ACMHOOK_conflictset:
+        ret = acm_conflictset(ssidref1);
+
     default:
         /* deny */
         break;
index d58c49fcd4b81fc2941cc89d011e36bee2110bd9..01eae51bb2902cced570b3e9c8dcc6288986085b 100644 (file)
@@ -899,8 +899,10 @@ struct acm_operations acm_simple_type_enforcement_ops = {
     .fail_grant_map_ref     = NULL,
     .pre_grant_setup        = ste_pre_grant_setup,
     .fail_grant_setup       = NULL,
+    /* generic domain-requested decision hooks */
     .sharing                = ste_sharing,
     .authorization          = ste_authorization,
+    .conflictset            = NULL,
 
     .is_default_policy      = ste_is_default_policy,
 };